package com.migu.rbac.documented;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.lang.reflect.Method;

/**
 * @Description TODO :
 * @Author: zj
 * @Date: 9:56 2019/2/28
 * @Version 1.0
 **/
@Aspect
@Component
public class OperateAspect {

    //切入点
    @Pointcut("@annotation(com.migu.rbac.documented.MyTest)")
    public void annotationPointCut() {

    }

    //前置通知
    @Before("annotationPointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //获取类型
        MyTest annotation = method.getAnnotation(MyTest.class);
        System.out.println(annotation.evenName());

        System.out.print("打印：" + annotation + " 开始前");
    }

    // 所有方法的执行作为切入点
    @AfterThrowing(throwing = "ex"
            , pointcut = "annotationPointCut()")
    // 声明ex时指定的类型会限制目标方法必须抛出指定类型的异常
    // 此处将ex的类型声明为Throwable，意味着对目标方法抛出的异常不加限制
    public void doRecoveryActions(Throwable ex) {
        System.out.println("目标方法中抛出的异常:" + ex);
        System.out.println("模拟Advice对异常的修复...");
    }


    /*@Around("annotationPointCut()")
    public Object serviceExceptionHandler(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature sig = joinPoint.getSignature();
        if (!(sig instanceof MethodSignature)) {
            return joinPoint.proceed(); // result的值就是被拦截方法的返回值
        }
        MethodSignature msig = (MethodSignature) sig;
        Method currentMethod = msig.getMethod();
        //获取类型
        MyTest annotation = currentMethod.getAnnotation(MyTest.class);
        System.out.println(annotation.evenName());

        System.out.print("打印：" + annotation + " 开始前");
        return null;
    }*/

    @After("annotationPointCut()")
    public void after() {
        System.out.println("after执行之后");
    }

}
